package com.example.blog.module.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.blog.module.component.MyElasticsearchRepository;
import com.example.blog.module.entity.Article;
import com.example.blog.module.mapper.ArticleMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDateTime;

/**
 * @author 郑家莽
 */
@Component
@RequiredArgsConstructor
public class ThreadService {

    private final MyElasticsearchRepository myElasticsearchRepository;

    //期望此操作在线程池执行不会影响原有主线程
    //这里线程池不了解可以去看JUC并发编程

    /**
     * 指定 taskExecutor 线程池来执行这个 异步 方法，评论数异步更新，不影响用户体验
     * @param articleService
     * @param article
     */
    @Async("taskExecutor")
    public void updateArticleCommentCounts(ArticleService articleService, Article article) {

        Integer commontCounts = article.getCommentCounts();
        Article articleupdate = new Article();

        //更新 评论数
        articleupdate.setCommentCounts(commontCounts+1);

        //更新 热度
        LocalDateTime createDate = article.getCreateDate();
        LocalDateTime now = LocalDateTime.now();
        Duration duration = Duration.between(createDate, now);
        Double seconds = Double.valueOf(duration.toSeconds());
        articleupdate.setHotness((article.getViewCounts() + 5 * (article.getCommentCounts()+1)) / ( seconds / 86400));

        LambdaQueryWrapper<Article> updatewrapper = new LambdaQueryWrapper<>();
        //根据id更新
        updatewrapper.eq(Article::getId ,article.getId());
        //设置一个为了在多线程的环境下线程安全
        //改之前再确认这个值有没有被其他线程抢先修改，类似于CAS操作 cas加自旋，加个循环就是cas
        updatewrapper.eq(Article ::getCommentCounts,commontCounts);
        // update article set view_count=100 where view_count=99 and id =111
        //实体类加更新条件
        articleService.update(articleupdate,updatewrapper);

        //同步es
        articleupdate.setId(article.getId());
        myElasticsearchRepository.save(articleupdate);

        try {
            Thread.sleep(5000);
            System.out.println("更新完成了");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Async("taskExecutor")
    public void updateEsArticle(Article article){
        myElasticsearchRepository.save(article);
    }

}


